#include <iostream>
#include <string>
#include <sw/redis++/redis++.h>
#include <gflags/gflags.h>
#include <thread>

typedef sw::redis::Redis redis_t;

DEFINE_string(ip, "127.0.0.1", "这是服务器的IP地址, 格式: 127.0.0.1");
DEFINE_int32(port, 6379, "这个是服务器的端口， 格式： 6379");
DEFINE_int32(db, 0, "库的编号， 默认为0号");
DEFINE_bool(keep_alive, true, "是否进行长连接保活");

void print_redis(redis_t& client, const std::string& key)
{
    // 获取字符串键值对
    auto user = client.get(key);
    if(user)
    {
        std::cout << *user << std::endl;
    }
}

//字符串键值对的操作
void add_string(redis_t& client)
{
    //添加字符串键值对
    client.set("会话ID1", "用户ID1");
    client.set("会话ID2", "用户ID2");
    client.set("会话ID3", "用户ID3");
    client.set("会话ID4", "用户ID4");
    client.set("会话ID5", "用户ID5");

    //修改---数据已存在则进行修改，不存在则新增
    client.set("会话ID3", "用户ID333333333");

    //删除字符串键值对
    // client.del("会话ID1");
    // client.del("会话ID2");
    // client.del("会话ID3");
    // client.del("会话ID4");
    client.del("会话ID5");

    print_redis(client, "会话ID1");
    print_redis(client, "会话ID2");
    print_redis(client, "会话ID3");
    print_redis(client, "会话ID4");
    print_redis(client, "会话ID5");
}

//有效时间的控制
void expired_test(redis_t& client)
{
    client.expire("会话ID1", std::chrono::seconds(5));
    client.set("会话ID6", "用户ID6666666", std::chrono::seconds(5));

    print_redis(client, "会话ID1");
    print_redis(client, "会话ID6");
    std::this_thread::sleep_for(std::chrono::seconds(6));
    std::cout << "休眠2秒之后: " << std::endl;
    print_redis(client, "会话ID1");
    print_redis(client, "会话ID6");
}

//列表数据的操作
void list_test(redis_t& client)
{
    //右插
    client.rpush("群聊1", "成员1");
    client.rpush("群聊1", "成员2");
    client.rpush("群聊1", "成员3");
    client.rpush("群聊1", "成员4");
    client.rpush("群聊1", "成员5");

    //左获取
    std::vector<std::string> users;
    //最后一个参数不能直接传，需要使用 stdLLback_inserter(users) 包裹users；
    client.lrange("群聊1", 0, -1, std::back_inserter(users));
    for(auto& user : users)
    {
        std::cout << user << std::endl;
    }
}

int main(int argc, char* argv[])
{
    //对命令行参数的解析
    google::ParseCommandLineFlags(&argc, &argv, true);

    //功能接口的演示中
    //1. 构造连接选项实例化，Redis对象，连接服务器
    sw::redis::ConnectionOptions opts;
    opts.host = FLAGS_ip;
    opts.port = FLAGS_port;
    opts.db = FLAGS_db;
    opts.keep_alive = FLAGS_keep_alive;

    redis_t client(opts);
    //2. 添加字符串键值对，删除字符串键值对，获取字符串键值对 
    add_string(client);
    //3. 实现控制数据有效时间的操作
    std::cout << "------------------------------------------" << std::endl;
    expired_test(client);
    std::cout << "------------------------------------------" << std::endl;
    //4.列表操作，主要实现数据的右插，左获取
    list_test(client);
}